package com.mark.web.stars.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mark.common.Constant;
import com.mark.common.exception.DataException;
import com.mark.common.utils.DBExecutorResultUtil;
import com.mark.web.common.service.IRedisCacheService;
import com.mark.web.stars.entity.po.ProperNoun;
import com.mark.web.stars.entity.po.ProperNounDictType;
import com.mark.web.stars.entity.vo.ProperNounVO;
import com.mark.web.stars.mapper.ProperNounDictTypeMapper;
import com.mark.web.stars.mapper.ProperNounMapper;
import com.mark.web.stars.service.IProperNounService;
import com.mark.web.sys.entity.vo.DictVo;
import com.mark.web.sys.service.IDictService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 单词-专有名词 Service层接口实现
 * @Author: Mark
 * @CreateDate: 2020/5/23 19:27
 * @Copyright : 豆浆油条个人非正式工作室
 */
@Service
public class ProperNounServiceImpl implements IProperNounService {

    private static final int DEFAULT_TIMES = 1;
    private static final String PROPER_NOUN_TYPE_PRE = "ProperNounTypeId:";

    @Autowired
    private ProperNounMapper properNounMapper;
    @Autowired
    private ProperNounDictTypeMapper properNounDictTypeMapper;
    @Autowired
    private IDictService iDictService;
    @Autowired
    private IRedisCacheService iRedisCacheService;


    @Override
    public List<Map<String, Object>> getProperNounDictTypeList() {
        List<Map<String, Object>> result;
        final int properNounDictTypeId = Constant.CampusProperties.PROPER_NOUN_DICT_ID;
        //首先尝试从缓存中获取
        final String cacheKey = PROPER_NOUN_TYPE_PRE + properNounDictTypeId;
        List<Object> listRange = iRedisCacheService.getListRange(cacheKey, 0, 0);
        if (CollectionUtils.isEmpty(listRange)) {
            //没有命中缓存，则查询DB
            List<DictVo> dictVoList = iDictService.getDictByParentId(properNounDictTypeId);
            List<Map<String, Object>> collect = dictVoList.stream().map(dictVo -> {
                Map<String, Object> map = Maps.newHashMap();
                map.put("id", dictVo.getId());
                map.put("name", dictVo.getName());
                return map;
            }).collect(Collectors.toList());
            //将查询结果缓存起来
            iRedisCacheService.listPush(cacheKey, collect);
            result = collect;
        }else{
            result = (List<Map<String, Object>>) listRange.get(0);
        }
        return result;
    }

    @Override
    public PageInfo<ProperNounVO> getProperNounList(int pageNum, int pageSize, String content) {
        PageHelper.startPage(pageNum, pageSize);
        List<ProperNounDictType> properNounDictTypes = properNounDictTypeMapper.selectByCondition(content);
        List<ProperNounVO> properNounVOList = Lists.newArrayList();

        //获取该专有名词的字典类型
        List<Map<String, Object>> properNounDictTypeList = getProperNounDictTypeList();
        Map<Integer, String> dictMap = Maps.newHashMap();
        for (Map<String, Object> map : properNounDictTypeList) {
            Integer key = (Integer) map.get("id");
            String value = (String) map.get("name");
            dictMap.put(key, value);
        }

        for (ProperNounDictType properNounDictType : properNounDictTypes) {
            ProperNoun properNoun = properNounDictType.getProperNoun();
            List<Integer> fkDictIdList = properNounDictType.getFkDictIdList();
            List<String> dictNameList = parseDictName(fkDictIdList,dictMap);
            ProperNounVO properNounVO = new ProperNounVO(properNoun, dictNameList);
            properNounVOList.add(properNounVO);
        }
        PageInfo<ProperNounVO> result = new PageInfo<>(properNounVOList);
        result.setTotal(new PageInfo<>(properNounDictTypes).getTotal());
        return result;
    }

    private List<String> parseDictName(List<Integer> fkDictIdList, Map<Integer, String> dictMap) {
        List<String> result = Lists.newArrayList();
        for (Integer dictId : fkDictIdList) {
            String name = dictMap.get(dictId);
            if (StringUtils.isNotBlank(name)) {
                result.add(name);
            }
        }
        return result;
    }


    @Transactional(value = "myStarsTransactionManager")
    @Override
    public void add(String content, String description, Integer[] checkedTypeIdList) {
        ProperNoun properNoun = new ProperNoun();
        properNoun.setContent(content);
        properNoun.setDescription(description);
        properNoun.setTimes(DEFAULT_TIMES);
        int effectNum = properNounMapper.insert(properNoun);
        DBExecutorResultUtil.effectRowIsNotOne(effectNum,"插入数据失败！！");
        effectNum = properNounDictTypeMapper.insert(properNoun.getId(), new ArrayList<Integer>(Arrays.asList(checkedTypeIdList)));
        if (effectNum < 1) {
            throw new DataException("插入类型数据失败！");
        }
    }

    @Transactional(value = "myStarsTransactionManager")
    @Override
    public void delete(int id) {
        int effectNum = properNounMapper.deleteByPrimaryKey(id);
        DBExecutorResultUtil.effectRowIsNotOne(effectNum,"删除专有名词失败！");
        effectNum = properNounDictTypeMapper.deleteByFkProperId(id);
        if(effectNum < 1){
            throw new DataException("删除专有名词字典记录失败！");
        }
    }
}
